package com.hsd.whb.controller;

import com.hsd.whb.converter.DeviceConverter;
import com.hsd.whb.entity.*;
import com.hsd.whb.enums.LanguageEnum;
import com.hsd.whb.enums.MeetingStatusEnum;
import com.hsd.whb.enums.ResultEnum;
import com.hsd.whb.exception.HwbException;
import com.hsd.whb.pojo.output.MeetingVO;
import com.hsd.whb.pojo.query.QueryMeeting;
import com.hsd.whb.properties.PersonProperties;
import com.hsd.whb.service.*;
import com.hsd.whb.utils.*;
import com.hsd.whb.pojo.output.DeviceVO;
import com.hsd.whb.pojo.output.ResultVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.*;

@Controller
@RequestMapping("/recorder")
public class RecorderController {

    @Autowired
    private RecorderService recorderService;

    @Autowired
    private ManagerService managerService;

    @Autowired
    private MeetingService meetingService;

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private ParticipantsService participantsService;

    @Autowired
    private MeetingParticipantsService meetingParticipantsService;

    @GetMapping("/modifyInfo")
    public String toModifyInfo() {
        return "recorder/recorderForm";

    }

    @PostMapping("/modifyInfo")
    @ResponseBody
    public ResultVO modifyInfo(@Valid Recorder recorder, BindingResult bindingResult) {
        ValidatorUtil.valid(bindingResult);
        recorderService.updateRecorder(recorder);
        return ResultVOUtil.success("修改成功");
    }

    @GetMapping("/getOneselfInfo")
    @ResponseBody
    public Recorder getOneselfInfo() {
        return recorderService.findByUsername(SecurityUtil.getUsername());
    }

    @GetMapping("/fileRecordList")
    public String toFileRecordList() {
        return "recorder/fileRecordList";
    }

    @GetMapping("/stayOpenFileRecordList")
    public String tostayOpenFileRecordList() {
        return "recorder/stayOpenFileRecordList";
    }

    @PostMapping("/findFileRecordList")
    @ResponseBody
    public List<Meeting> findFileRecordList(@PageableDefault(sort = "startTime", direction = Sort.Direction.DESC) Pageable pageable,
                                            QueryMeeting queryMeeting) {
        return meetingService.findFileRecordListByRecorder(pageable, SecurityUtil.getUsername(), queryMeeting);
    }

    @GetMapping("/findFileRecordList")
    @ResponseBody
    public long findFileRecordListTotalPages(Integer size, QueryMeeting queryMeeting) {
        long totalNum = meetingService.findFileRecordListTotalPagesByRecorder(SecurityUtil.getUsername(), queryMeeting);
        ;
        return (long) Math.ceil(totalNum / (double) size);
    }

    @PostMapping("/findStayOpenFileRecordList")
    @ResponseBody
    public List<MeetingVO> findStayOpenFileRecordList(@PageableDefault(sort = "startTime", direction = Sort.Direction.DESC) Pageable pageable,
                                                      QueryMeeting queryMeeting) {
        return meetingService.findStayOpenFileRecordListByRecorder(pageable, SecurityUtil.getUsername(), queryMeeting);
    }

    @GetMapping("/findStayOpenFileRecordList")
    @ResponseBody
    public long findStayOpenFileRecordListTotalPages(Integer size, QueryMeeting queryMeeting) {
        long totalNum = meetingService.findStayOpenFileRecordListTotalPagesByRecorder(SecurityUtil.getUsername(), queryMeeting);
        ;
        return (long) Math.ceil(totalNum / (double) size);
    }


    @GetMapping("/addFileRecord")
    public String toAddFileRecord() {
        return "recorder/addFileRecordForm";
    }

    @GetMapping("/getDeviceListByManagerId")
    @ResponseBody
    public List<DeviceVO> getDeviceListByManagerId() {
        Recorder recorder = recorderService.findByUsername(SecurityUtil.getUsername());
        return deviceService.findDeviceByManagerId(recorder.getManagerId());
    }

    @GetMapping("/showFileRecord/{meetingId}")
    public String toShowFileRecord(@PathVariable("meetingId") Integer meetingId, HttpServletRequest request) {
        request.setAttribute("meetingId", meetingId);
        return "recorder/showFileRecord";
    }

    @PostMapping("/addFileRecord")
    @ResponseBody
    public ResultVO addFileRecord(@Valid Meeting meeting, BindingResult bindingResult) {
        ValidatorUtil.valid(bindingResult);
        Recorder recorder = recorderService.findByUsername(SecurityUtil.getUsername());
        meeting.setManagerId(recorder.getManagerId());
        meeting.setRecorderId(recorder.getId());
        meeting.setMeetingStatus(MeetingStatusEnum.PENDING.getCode());
        meeting.setDeleted(0);
        meeting = meetingService.save(meeting);
        ResultVO resultVO = ResultVOUtil.success();
        resultVO.setData(meeting.getId());
        return resultVO;
    }

    @GetMapping("/getEnterpriseInfo")
    @ResponseBody
    public Manager getEnterpriseInfo() {
        Recorder recorder = recorderService.findByUsername(SecurityUtil.getUsername());
        Manager manager = managerService.findById(recorder.getManagerId());
        return manager;
    }

    @GetMapping("/getDeviceInfoByMeetingId")
    @ResponseBody
    public DeviceVO getDeviceInfoById(Integer id) {
        Meeting meeting = meetingService.findMeetingById(id);
        Device device = deviceService.findDeviceById(meeting.getDeviceId());
        return DeviceConverter.convertToDeviceVO(device);
    }


    @PostMapping("/speak/refresh")
    @ResponseBody
    public ResultVO refreshSpeak(String username, Integer meetingId, HttpServletRequest request) {
        meetingService.updateSpeakUsername(meetingId, username, request.getServletContext());
        return ResultVOUtil.success();
    }

    @PostMapping("/addMeetingParticipator")
    @ResponseBody
    public ResultVO addMeetingParticipator(String username, Integer meetingId) {
        meetingParticipantsService.saveMeetingParticipants(meetingId, username);
        return ResultVOUtil.success();
    }

    @GetMapping("/getMeetingParticipators")
    @ResponseBody
    public ResultVO getMeetingParticipators(Integer meetingId) {
        List<Integer> ids = meetingParticipantsService.getParticipantsIdByMeetingId(meetingId);
        List<Participants> list = participantsService.findParticipantsByIdInList(ids);
        return ResultVOUtil.success(list);
    }

    @PostMapping("/startMeeting")
    @ResponseBody
    public ResultVO startMeeting(Integer id, Integer language, HttpServletRequest request) {
        Meeting meeting = meetingService.startMeeting(id, request.getServletContext(), language);
        return ResultVOUtil.success(EnumUtil.getStringByCode(meeting.getMeetingStatus(), MeetingStatusEnum.class));
    }

    @PostMapping("/endMeeting")
    @ResponseBody
    public ResultVO endMeeting(Integer id, HttpServletRequest request) {
        String nowSpeak = (String) request.getSession().getAttribute("nowSpeak");
        Meeting meeting = meetingService.endMeeting(id, nowSpeak, request.getServletContext());
        request.getSession().removeAttribute("prevSpeak");
        request.getSession().removeAttribute("nowSpeak");
        return ResultVOUtil.success(EnumUtil.getStringByCode(meeting.getMeetingStatus(), MeetingStatusEnum.class));
    }


    @PostMapping("/pauseMeeting")
    @ResponseBody
    public ResultVO pauseMeeting(Integer id, HttpServletRequest request) {
        Meeting meeting = meetingService.pauseMeeting(id, request.getServletContext());
        return ResultVOUtil.success(EnumUtil.getStringByCode(meeting.getMeetingStatus(), MeetingStatusEnum.class));
    }

    @PostMapping("/restartMeeting")
    @ResponseBody
    public ResultVO restartMeeting(Integer id, Integer language, HttpServletRequest request) {
        Meeting meeting = meetingService.restartMeeting(id, request.getServletContext(), language);
        return ResultVOUtil.success(EnumUtil.getStringByCode(meeting.getMeetingStatus(), MeetingStatusEnum.class));
    }

    @GetMapping("/getLanguageList")
    @ResponseBody
    public List<Map<String, Object>> getLanguageList() {
        return EnumUtil.getEnumInfo(LanguageEnum.class, "id", "language");
    }

    @PostMapping("/changeLanguage")
    @ResponseBody
    public ResultVO changeLanguage(Integer id, Integer language, HttpServletRequest request) {
        meetingService.changeLanguage(id, request.getServletContext(), language);
        return ResultVOUtil.success();
    }
}
